﻿using Soft.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Soft.Service
{
    public struct FunctionCode : IFunctionCode
    {

        /// <summary>
        /// 实例名最大的长度
        /// </summary>
        public static int INSTANCE_MAX_SIZE = 128;


        /// <summary>
        /// 最大功能索引号格式 0000
        /// </summary>
        private const string FUNCTION_INDEX_FORMAT = "00000";


        /// <summary>
        /// 最大功能号索引 9999
        /// </summary>
        private const uint MAX_FUNCTION_INDEX = 99999U;


        /// <summary>
        /// 操作类型 格式
        /// </summary>
        private const string FUNCTION_OPERATOR_FORMAT = "0";


        /// <summary>
        /// 最大操作类型功能号 
        /// </summary>
        private const uint MAX_FUNCTION_OPERATOR = 4U;


        /// <summary>
        /// 重写索引的格式
        /// </summary>
        private const string OVERRIDE_INDEX_FORMAT = "0";


        /// <summary>
        ///重写的最大索引
        /// </summary>
        private const uint MAX_OVERRIDE_INDEX = 9U;


        /// <summary>
        /// 实例名
        /// </summary>
        private string _InstanceName;


        /// <summary>
        /// 功能识别码
        /// </summary>
        /// <param name="flag">系统模块表示</param>
        /// <param name="functionIndex">功能号索引</param>
        /// <param name="functionOperator">操作类型</param>
        /// <param name="overrideIndex">重写索引</param>
        public FunctionCode(MesMethodFlag flag, uint functionIndex, FunctionOperator functionOperator, uint overrideIndex)
        {
            if (functionIndex > 99999U)
            {
                throw new ArgumentOutOfRangeException("functionIndex", string.Format("范围在：0 - {0}", 99999U));
            }
            if (overrideIndex > 9U)
            {
                throw new ArgumentOutOfRangeException("overrideIndex", string.Format("范围在：0 - {0}", 9U));
            }
            this._InstanceName = string.Empty;
            this.Flag = flag;
            this.FunctionIndex = functionIndex;
            this.Operator = functionOperator;
            this.OverrideIndex = overrideIndex;
            this.Code = this.Flag.ToString().ToUpper() + this.FunctionIndex.ToString("00000") + ((byte)this.Operator).ToString("0") + this.OverrideIndex.ToString("0");
        }

        /// <summary>
        /// 功能识别码
        /// </summary>
        /// <param name="flag">系统模块表示</param>
        /// <param name="functionIndex">功能号索引</param>
        /// <param name="overrideIndex">重写索引</param>
        public FunctionCode(MesMethodFlag flag, uint functionIndex, uint functionOperator, uint overrideIndex)
        {
            if (functionIndex > 99999U)
            {
                throw new ArgumentOutOfRangeException("functionIndex", string.Format("范围在：0 - {0}", 99999U));
            }
            if (functionOperator > 4U)
            {
                throw new ArgumentOutOfRangeException("functionOperator", string.Format("范围在：0 - {0}", 4U));
            }
            if (overrideIndex > 9U)
            {
                throw new ArgumentOutOfRangeException("overrideIndex", string.Format("范围在：0 - {0}", 9U));
            }
            this._InstanceName = string.Empty;
            this.Flag = flag;
            this.FunctionIndex = functionIndex;
            this.Operator = (FunctionOperator)functionOperator;
            this.OverrideIndex = overrideIndex;
            this.Code = this.Flag.ToString().ToUpper() + this.FunctionIndex.ToString("00000") + functionOperator.ToString("0") + this.OverrideIndex.ToString("0");
        }


        /// <summary>
        /// 系统模块表示
        /// </summary>
        public MesMethodFlag Flag { get; private set; }


        /// <summary>
        /// 功能号索引
        /// </summary>
        public uint FunctionIndex { get; private set; }


        /// <summary>
        /// 操作类型
        /// </summary>
        public FunctionOperator Operator { get; private set; }


        /// <summary>
        /// 重写索引
        /// </summary>
        public uint OverrideIndex { get; private set; }


        /// <summary>
        ///实例名称 
        /// </summary>
        public string InstanceName
        {
            get
            {
                return this._InstanceName;
            }
            set
            {
                this._InstanceName = value.Trim().ToUpper();
            }
        }

 
        /// <summary>
        /// 功能号
        /// </summary>
        public string Code { get; private set; }


        /// <summary>
        /// 实例名+功能号 
        /// </summary>
        public string FullCode
        {
            get
            {
                if (string.IsNullOrWhiteSpace(this._InstanceName))
                {
                    return this.Code;
                }
                return this._InstanceName + "." + this.Code;
            }
        }


        /// <summary>
        /// toString方法
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return this.Code;
        }


        /// <summary>
        /// 正则匹配 是否是功能识别码
        /// </summary>
        /// <param name="functionCode"></param>
        /// <param name="onlyCode"></param>
        /// <returns></returns>
        public static bool IsFunctonCode(string functionCode, bool onlyCode = false)
        {
            if (!string.IsNullOrWhiteSpace(functionCode))
            {
                functionCode = functionCode.Trim();
                if (ToolsClass.RegexTest(onlyCode ? "^[a-zA-Z]{3,5}\\d{7}$" : ("^([a-zA-Z]\\w{0," + (FunctionCode.INSTANCE_MAX_SIZE - 1).ToString() + "}\\.)?[a-zA-Z]{3,5}\\d{7}$"), functionCode))
                {
                    int num = functionCode.IndexOf('.');
                    if (num > -1)
                    {
                        functionCode = functionCode.Substring(num + 1);
                    }
                    Match match = Regex.Match(functionCode, "^[a-zA-Z]+");
                    return match.Success && Enum.IsDefined(typeof(MesMethodFlag), match.Value);
                }
            }
            return false;
        }


        /// <summary>
        /// 将字符串解析为功能号
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static FunctionCode Parse(string s)
        {
            if (FunctionCode.IsFunctonCode(s, false))
            {
                string instanceName = string.Empty;
                int num = s.IndexOf('.');
                if (num > -1)
                {
                    instanceName = s.Substring(0, num);
                    s = s.Substring(num + 1);
                }
                Match match = Regex.Match(s, "^[a-zA-Z]+");
                if (match.Success && Enum.IsDefined(typeof(MesMethodFlag), match.Value))
                {
                    MesMethodFlag flag = match.Value.ConvertTo(MesMethodFlag.DEMO, true);
                    match = Regex.Match(s, "\\d+$");
                    if (match.Success)
                    {
                        return new FunctionCode(flag, match.Value.Substring(0, 5).ConvertTo(0U, true), match.Value.Substring(5, 1).ConvertTo(FunctionOperator.Create, true), match.Value.Substring(6, 1).ConvertTo(0U, true))
                        {
                            InstanceName = instanceName
                        };
                    }
                }
            }
            throw new FormatException(string.Concat(new string[]
            {
                "Conversion of the string '",
                s,
                "' to ",
                typeof(FunctionCode).FullName,
                " object failed."
            }));
        }


        /// <summary>
        /// 将string 转换为functionCode
        /// </summary>
        /// <param name="value"></param>
        public static implicit operator FunctionCode(string value)
        {
            return FunctionCode.Parse(value);
        }


 
    }
}
